package org.csu.mybigpro.controller;

import org.csu.mybigpro.common.CommonResponse;
import org.csu.mybigpro.domain.Exam;
import org.csu.mybigpro.service.IExamService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;


import java.io.ByteArrayInputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/exams")
public class ExamController {

    @Autowired
    private IExamService examService;

    @PostMapping("/generate")
    public CommonResponse<Exam> generateExam(@RequestBody Map<String, String> payload) {
        try {
            String description = payload.get("description");
            if (description == null || description.isBlank()) {
                return CommonResponse.createForError("Exam description cannot be empty.");
            }
            Exam exam = examService.generateExam(description);
            return CommonResponse.createForSuccess("Exam generated successfully", exam);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Failed to generate exam", e);
        }
    }

    @PostMapping("/{id}/publish")
    public CommonResponse<Exam> publishExam(@PathVariable Long id, @RequestBody Map<String, Integer> payload) {
        try {
            Integer duration = payload.get("durationInMinutes");
            if (duration == null || duration <= 0) {
                return CommonResponse.createForError("Invalid duration.");
            }
            Exam exam = examService.publishExam(id, duration);
            return CommonResponse.createForSuccess("Exam published successfully", exam);
        } catch (IllegalArgumentException e) {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, e.getMessage(), e);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Failed to publish exam", e);
        }
    }

    /**
     * 【新接口】获取所有试卷列表
     */
    @GetMapping
    public CommonResponse<List<Exam>> getAllExams() {
        List<Exam> exams = examService.list();
        return CommonResponse.createForSuccess("Exams fetched successfully", exams);
    }

    /**
     * 【新接口】获取单份试卷详情
     */
    @GetMapping("/{id}")
    public CommonResponse<Exam> getExamById(@PathVariable Long id) {
        Exam exam = examService.getById(id);
        if (exam == null) {
            return CommonResponse.createForError("Exam not found");
        }
        return CommonResponse.createForSuccess("Exam details fetched successfully", exam);
    }

    /**
     * 【新接口】导出试卷为Word文档
     */
    @GetMapping("/{id}/export")
    public ResponseEntity<InputStreamResource> exportExamToWord(@PathVariable Long id) {
        try {
            Exam exam = examService.getById(id);
            if (exam == null) {
                return ResponseEntity.notFound().build();
            }

            ByteArrayInputStream bis = examService.exportExamToWord(exam);
            String fileName = URLEncoder.encode(exam.getTitle() + ".docx", StandardCharsets.UTF_8).replaceAll("\\+", "%20");

            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + fileName);

            return ResponseEntity
                    .ok()
                    .headers(headers)
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(new InputStreamResource(bis));

        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}